home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / Macintosh Drag and Drop / Demo Applications / Dragster / DragText Sources / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-03  |  10.5 KB  |  493 lines  |  [TEXT/KAHL]

  1. /*
  2.  *
  3.  *        event.c
  4.  *
  5.  *        Event handling routines.
  6.  *        
  7.  *
  8.  *        Author:        Rob Johnston
  9.  *        Date:        Monday, Janurary 20, 1992
  10.  *
  11.  *        12/30/94    JML        Code now compiles with Universal interfaces.
  12.  *
  13.  *        Copyright © 1992 Apple Computer, Inc.
  14.  *
  15.  */
  16.  
  17.  
  18. /*
  19.  *    Debugging Aids :
  20.  *
  21.  *    Turn this flag on to see where the current hilite region is.
  22.  *
  23.  *        #define    _FLASH_HILITE_RGN_
  24.  *
  25.  */
  26.  
  27.  
  28. #include <Drag.h>
  29. #include <Desk.h>
  30. #include <AppleEvents.h>
  31. #include "globals.h"
  32. #include "prototypes.h"
  33. #include "DTResources.h"
  34.  
  35.  
  36. #define    SleepDuration        20        /* WaitNextEvent sleep constant        */
  37.  
  38.  
  39. /*
  40.  *    DoContent handles mouseDown events in the content region of a document window.
  41.  *
  42.  *    (1)    If the mouseDown is on a control, handle the click by calling TrackControl.
  43.  *
  44.  *    (2)    If the mouseDown is on a draggable object (the document's hiliteRgn) and a
  45.  *        successful drag occurs, no further processing is necessary.
  46.  *
  47.  *    (3)    If the mouseDown is on a draggable object and the mouse is released without
  48.  *        dragging, set the insertion point to the original mouseDown location by calling
  49.  *        TEClick with the mouseDown information.
  50.  *
  51.  *    (4)    If the mouseDown is not on a draggable object and within the viewRect of the
  52.  *        TextEdit field, call TEClick to handle the mouseDown.
  53.  */
  54.  
  55. void DoContent(Document *theDocument, EventRecord *theEvent)
  56.  
  57. {    short            thePart;
  58.     Point            thePoint;
  59.     ControlHandle    theControl;
  60.  
  61.     SetPort(theDocument->theWindow);
  62.     thePoint = theEvent->where;
  63.     GlobalToLocal(&thePoint);
  64.  
  65.     if (thePart = FindControl(thePoint, theDocument->theWindow, &theControl)) {
  66.         if (theControl == theDocument->vScroll) {
  67.             if (thePart == inThumb) {
  68.                 TrackControl(theControl, thePoint, 0L);
  69.                 AdjustDocumentView(theDocument);
  70.             } else {
  71.                 TrackControl(theControl, thePoint, &ScrollProc);
  72.             }
  73.             AdjustScrollBar(theDocument);
  74.         }
  75.     } else if (PtInRgn(thePoint, theDocument->hiliteRgn)) {
  76.         if (!DragText(theDocument, theEvent, theDocument->hiliteRgn)) {
  77.             TEClick(thePoint, false, theDocument->theTE);
  78.         }
  79.     } else if (PtInRect(thePoint, &(**(theDocument->theTE)).viewRect)) {
  80.             TEClick(thePoint, (theEvent->modifiers & shiftKey) != 0,
  81.                     theDocument->theTE);
  82.     }
  83.  
  84.     TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  85. }
  86.  
  87.  
  88. /*
  89.  *    DoBackgroundContent handles mouseDown events in the content region of a document window
  90.  *    when the window is not frontmost. The following bullet items describe how this background
  91.  *    mouseDown event is handled:
  92.  *
  93.  *    (1)    If the mouseDown is not in a draggable object (not in the document's hiliteRgn) call
  94.  *        SelectWindow to bring the window to the front as usual.
  95.  *
  96.  *    (2)    If the mouseDown is in a draggable object and the mouse is released without
  97.  *        dragging, call SelectWindow when the mouse is released.
  98.  *
  99.  *    (3)    If the mouseDown is in a draggable object and a successful drag occurs, SelectWindow
  100.  *        should only be called if the drop occurred in the same window (the DragText function
  101.  *        calls SelectWindow in this case).
  102.  */
  103.  
  104. void DoBackgroundContent(Document *theDocument, EventRecord *theEvent)
  105.  
  106. {    short            thePart;
  107.     Point            thePoint;
  108.     ControlHandle    theControl;
  109.  
  110.     SetPort(theDocument->theWindow);
  111.     thePoint = theEvent->where;
  112.     GlobalToLocal(&thePoint);
  113.  
  114.     if (PtInRgn(thePoint, theDocument->hiliteRgn)) {
  115.  
  116.         if (! DragText(theDocument, theEvent, theDocument->hiliteRgn)) {
  117.             SelectWindow(theDocument->theWindow);
  118.         }
  119.  
  120.     } else {
  121.  
  122.         SelectWindow(theDocument->theWindow);
  123.  
  124.     }
  125. }
  126.  
  127.  
  128. /*
  129.  *    DoMouseDown is called to handle mouseDown events.
  130.  */
  131.  
  132. void DoMouseDown(EventRecord *theEvent)
  133.  
  134. {    short        thePart;
  135.     WindowPtr    theWindow;
  136.     Rect        dragRect;
  137.     Document    *theDocument;
  138.  
  139.     thePart = FindWindow(theEvent->where, &theWindow);
  140.     switch(thePart) {
  141.         case inMenuBar:
  142.             PrepareMenus();
  143.             DoMenuCommand(MenuSelect(theEvent->where));
  144.             break;
  145.         case inSysWindow:
  146.             SystemClick(theEvent, theWindow);
  147.             break;
  148.         case inContent:
  149.             theDocument = IsDocumentWindow(theWindow);
  150.             if (theWindow == FrontWindow()) {
  151.                 DoContent(theDocument, theEvent);
  152.             } else {
  153.                 DoBackgroundContent(theDocument, theEvent);
  154.             }
  155.             break;
  156.         case inDrag:
  157.             if (theWindow != FrontWindow())
  158.                 SelectWindow(theWindow);
  159.             dragRect = qd.screenBits.bounds;
  160.             DragWindow(theWindow, theEvent->where, &dragRect);
  161.             break;
  162.         case inGrow:
  163.             if (theDocument = IsDocumentWindow(theWindow)) {
  164.                 GrowDocumentWindow(theWindow, theEvent->where);
  165.                 TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  166.             }
  167.             break;
  168.         case inGoAway:
  169.             if (theDocument = IsDocumentWindow(theWindow))
  170.                 if (TrackGoAway(theWindow, theEvent->where)) {
  171.                     CloseDocument(theDocument);
  172.                     PrepareMenus();
  173.                     DrawMenuBar();
  174.                 }
  175.             break;
  176.     }
  177. }
  178.  
  179.  
  180. /*
  181.  *    DoKey is called each time a character is typed on the keyboard to
  182.  *    be entered into a document window.
  183.  */
  184.  
  185. void DoKey(char theChar)
  186.  
  187. {    WindowPtr        theWindow;
  188.     Document        *theDocument;
  189.  
  190.     if (theWindow = FrontWindow()) {
  191.         if (theDocument = IsDocumentWindow(theWindow)) {
  192.             SetPort(theDocument->theWindow);
  193.             TEKey(theChar, theDocument->theTE);
  194.             AdjustScrollBar(theDocument);
  195.             theDocument->dirty = true;
  196.             TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  197.  
  198.             if ((theChar < 0x1C) || (theChar > 0x1F)) {
  199.                 DisableUndoDrag();
  200.             }
  201.         }
  202.     }
  203. }
  204.  
  205.  
  206. /*
  207.  *    DoKeyDown is called to handle keyDown or autoKey events.
  208.  */
  209.  
  210. void DoKeyDown(EventRecord *theEvent)
  211.  
  212. {    char        theChar;
  213.  
  214.     theChar = theEvent->message & charCodeMask;
  215.  
  216.     if (theEvent->modifiers & cmdKey) {
  217.         PrepareMenus();
  218.         DoMenuCommand(MenuKey(theChar));
  219.     } else {
  220.         DoKey(theChar);
  221.     }
  222. }
  223.  
  224.  
  225. /*
  226.  *    DoActivate is called in response to activate/deactivate events.
  227.  */
  228.  
  229. void DoActivate(EventRecord *theEvent)
  230.  
  231. {    WindowPtr        theWindow;
  232.     Document        *theDocument;
  233.  
  234.     if (theWindow = (WindowPtr) theEvent->message) {
  235.         if (theDocument = IsDocumentWindow(theWindow)) {
  236.             DoActivateDocument(theDocument, (theEvent->modifiers & activeFlag));
  237.         }
  238.     }
  239. }
  240.  
  241.  
  242. /*
  243.  *    DoUpdate is called in response to update events.
  244.  */
  245.  
  246. void DoUpdate(EventRecord *theEvent)
  247.  
  248. {    Document    *theDocument;
  249.  
  250.     if (theDocument = IsDocumentWindow((WindowPtr) theEvent->message))
  251.         UpdateWindow(theDocument);
  252. }
  253.  
  254.  
  255. /*
  256.  *    DoOSEvent is called in response to Operating System events.
  257.  */
  258.  
  259. void DoOSEvent(EventRecord *theEvent)
  260.  
  261. {    Document        *theDocument;
  262.  
  263.     switch ((theEvent->message >> 24) & 0x0FF) {
  264.         case suspendResumeMessage:
  265.             gInBackground = (theEvent->message & resumeFlag) == 0;
  266.             if (theDocument = IsDocumentWindow(FrontWindow()))
  267.                 DoActivateDocument(theDocument, !gInBackground);
  268.             break;
  269.     }
  270. }
  271.  
  272.  
  273. pascal OSErr MyHandleOAPP(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
  274.  
  275. {
  276.     DoNewDocument();
  277. }
  278.  
  279.  
  280. pascal OSErr MyHandleODOC(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
  281.  
  282. {    AEDescList        docList;
  283.     AEKeyword        keyword;
  284.     DescType        returnedType;
  285.     FSSpec            theFSSpec;
  286.     Size            actualSize;
  287.     long            itemsInList;
  288.     short            index;
  289.     OSErr            result;
  290.  
  291.     if (result = AEGetParamDesc(&theAppleEvent, keyDirectObject, typeAEList, &docList))
  292.         return(result);
  293.  
  294.     if (result = AECountItems(&docList, &itemsInList))
  295.         return(result);
  296.  
  297.     for (index = 1; index <= itemsInList; index++) {
  298.         if (result = AEGetNthPtr(&docList, index, typeFSS, &keyword,
  299.                                  &returnedType, (Ptr) &theFSSpec, sizeof(FSSpec), &actualSize))
  300.             return(result);
  301.  
  302.         DoOpenFile(&theFSSpec);
  303.     }
  304.     
  305. }
  306.  
  307.  
  308. pascal OSErr MyHandleQUIT(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
  309.  
  310. {    Document        *theDocument;
  311.  
  312.     gQuitting = true;
  313.     while ((gQuitting) && (theDocument = IsDocumentWindow(FrontWindow()))) {
  314.         CloseDocument(theDocument);
  315.     }
  316.     if (gQuitting)
  317.         gQuit = true;
  318. }
  319.  
  320.  
  321. /*
  322.  *    InitEvents
  323.  */
  324.  
  325. void InitEvents()
  326.  
  327. {
  328.     AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc(MyHandleOAPP), 0, false);
  329.     AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc(MyHandleODOC), 0, false);
  330.     AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc(MyHandleQUIT), 0, false);
  331. }
  332.  
  333.  
  334. /*
  335.  *    ScrollProc is the function used in a call to TrackControl for
  336.  *    scrolling a document window.
  337.  */
  338.  
  339. pascal void ScrollProc(ControlHandle theControl, short theCode)
  340.  
  341. {    short        delta = 0, pageDelta;
  342.     Document    *theDocument;
  343.     Rect        viewRect;
  344.  
  345.     if (theCode == 0)
  346.         return;
  347.  
  348.     theDocument = (Document *) (**theControl).contrlRfCon;
  349.     viewRect = (**(theDocument->theTE)).viewRect;
  350.     pageDelta = ((viewRect.bottom - viewRect.top) / ScrollResolution) - 1;
  351.  
  352.     switch(theCode) {
  353.         case inUpButton:
  354.             delta = -1;
  355.             break;
  356.         case inDownButton:
  357.             delta = 1;
  358.             break;
  359.         case inPageUp:
  360.             delta = -pageDelta;
  361.             break;
  362.         case inPageDown:
  363.             delta = pageDelta;
  364.             break;
  365.     }
  366.  
  367.     SetCtlValue(theControl, GetCtlValue(theControl) + delta);
  368.     AdjustDocumentView((Document *) (**theControl).contrlRfCon);
  369. }
  370.  
  371.  
  372. /*
  373.  *
  374.  */
  375.  
  376. void DoHighLevelEvent(EventRecord *theEvent)
  377.  
  378. {
  379.     AEProcessAppleEvent(theEvent);
  380. }
  381.  
  382.  
  383. /*
  384.  *    Each time WaitNextEvent returns an event to this application, DoEvent
  385.  *    is called to handle the event.
  386.  */
  387.  
  388. void DoEvent(EventRecord *theEvent)
  389.  
  390. {    WindowPtr        theWindow;
  391.     Document        *theDocument;
  392.  
  393.     if (theWindow = FrontWindow()) {
  394.         if (theDocument = IsDocumentWindow(theWindow)) {
  395.             gFrontDocument = theDocument;
  396.         }
  397.     }
  398.  
  399.     switch(theEvent->what) {
  400.         case mouseDown:
  401.             DoMouseDown(theEvent);
  402.             break;
  403.         case mouseUp:
  404.             break;
  405.         case keyDown:
  406.         case autoKey:
  407.             DoKeyDown(theEvent);
  408.             break;
  409.         case activateEvt:
  410.             DoActivate(theEvent);
  411.             break;
  412.         case updateEvt:
  413.             DoUpdate(theEvent);
  414.             break;
  415.         case osEvt:
  416.             DoOSEvent(theEvent);
  417.             break;
  418.         case kHighLevelEvent:
  419.             DoHighLevelEvent(theEvent);
  420.             break;
  421.     }
  422. }
  423.  
  424.  
  425. /*
  426.  *    DoIdle get called repetitively while the application is not doing
  427.  *    anything.
  428.  */
  429.  
  430. void DoIdle()
  431.  
  432. {    WindowPtr        theWindow;
  433.     Document        *theDocument;
  434.  
  435.     if (theWindow = FrontWindow()) {
  436.         if (theDocument = IsDocumentWindow(theWindow)) {
  437.             SetPort(theDocument->theWindow);
  438.             TEIdle(theDocument->theTE);
  439.  
  440. #ifdef _FLASH_HILITE_RGN_
  441.  
  442.             {    long            dTime;
  443.  
  444.                 InvertRgn(theDocument->hiliteRgn);
  445.                 Delay(10, &dTime);
  446.                 InvertRgn(theDocument->hiliteRgn);
  447.             }
  448. #endif
  449.  
  450.         }
  451.     }
  452. }
  453.  
  454.  
  455. /*
  456.  *    This is the main event loop of the program. It calls WaitNextEvent
  457.  *    and dispatches the returned event until gQuit is true.
  458.  */
  459.  
  460. void EventLoop()
  461.  
  462. {    short            gotEvent;
  463.     EventRecord        theEvent;
  464.     RgnHandle        theMouseRgn;
  465.     Point            theLoc;
  466.  
  467.     theMouseRgn = NewRgn();
  468.  
  469.     do {
  470.  
  471.         //
  472.         //    Removed this AdjustCursor because it would sometimes set cursor to I-Beam
  473.         //    just before receiving a drag event. I don't think its really needed anyway.
  474.         //
  475.  
  476. //        GetGlobalMouse(&theLoc);
  477. //        AdjustCursor(theLoc, theMouseRgn);
  478.  
  479.         gotEvent = WaitNextEvent(everyEvent, &theEvent, SleepDuration, theMouseRgn);
  480.  
  481.         if (gotEvent) {
  482.             AdjustCursor(theEvent.where, theMouseRgn);
  483.             DoEvent(&theEvent);
  484.             AdjustCursor(theEvent.where, theMouseRgn);
  485.         } else {
  486.             DoIdle();
  487.         }
  488.     } while (! gQuit);
  489.  
  490.     DisposeRgn(theMouseRgn);
  491. }
  492.  
  493.